package UMC.Web;


import UMC.Data.Utility;
import UMC.Web.UI.UISlider;

import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;


public class UISection implements UMC.Data.IJSON {

    public static class Editer {
        private WebMeta webMeta = new WebMeta();

        /**
         * @param section UISection 中的section
         * @param row     UISection 中的row
         */
        public Editer(int section, int row) {

            webMeta.put("section", section).put("row", row);

        }


        /**
         * 行更新，
         *
         * @param value       更新的组件
         * @param reloadSinge 是否是单行更新，还是整体更新
         * @return
         */
        public Editer add(UICell value, boolean reloadSinge) {
            if (reloadSinge) {
                webMeta.put("value", new WebMeta().cell(value)).put("method", "PUT").put("reloadSinle", true);
            } else {
                webMeta.put("value", new WebMeta().cell(value)).put("method", "PUT");

            }
            return this;
        }


        /**
         * 行删
         *
         * @return
         */
        public Editer delete() {
            webMeta.put("method", "DEL");
            return this;
        }

        /**
         * 行追加
         *
         * @param value 追加的组件
         * @return
         */
        public Editer append(UICell value) {
            webMeta.put("value", new WebMeta().cell(value)).put("method", "APPEND");
            return this;
        }

        /**
         * 行插入
         *
         * @param value 插入的组件
         * @return
         */
        public Editer insert(UICell value) {
            webMeta.put("value", new WebMeta().cell(value)).put("method", "INSERT");
            return this;
        }

        /**
         * 发送到客户端
         *
         * @param context     UMC上下文
         * @param ui          界面
         * @param endResponse 是否立刻返回客户端
         */
        public void sendTo(WebContext context, String ui, boolean endResponse) {
            context.event("UI.Edit", ui, webMeta, endResponse);

        }
    }

    WebMeta _header = new WebMeta();

    WebMeta _footer = new WebMeta();

    private UISection() {

    }

    public WebMeta header() {
        return _header;

    }

    public WebMeta footer() {
        return _footer;

    }

    private UIHeader _uiHeader;
    private UIHeader _uiFooter;
    private UIFootBar _footBar;
    private UITitle _title;

    public UIHeader getHeader() {
        return Utility.isNull(this.parent, this)._uiHeader;
    }

    public UISection title(UITitle title) {
        Utility.isNull(this.parent, this)._title = title;
        return this;
    }

    public UITitle title() {
        return Utility.isNull(this.parent, this)._title;
    }


    public UISection setFooter(UIHeader footer) {
        Utility.isNull(this.parent, this)._uiFooter = footer;
        return this;
    }

    public UIFootBar getFootBar() {
        return Utility.isNull(this.parent, this)._footBar;
    }

    public UISection setFootBar(UIFootBar footer) {
        Utility.isNull(this.parent, this)._footBar = footer;
        return this;
    }

    public UIHeader getFooter() {
        return Utility.isNull(this.parent, this)._uiFooter;
    }

    public UISection setHeader(UIHeader header) {
        Utility.isNull(this.parent, this)._uiHeader = header;
        return this;
    }

    public static UISection create(UIHeader header, UIFootBar footer) {
        return create(header, footer, null);
    }


    public static UISection create(UIHeader header, UIFootBar footer, UITitle title) {
        UISection t = new UISection();
        t.Sections = new LinkedList<>();
        t.Sections.add(t);
        t._components = new LinkedList<>();
        t._uiHeader = header;
        t._footBar = footer;
        t._title = title;
        return t;
    }

    public static UISection create(UITitle title, UIFootBar footer) {

        return create(null, footer, title);
    }

    public static UISection create(UITitle title) {

        return create(null, null, title);

    }

    public static UISection create(UIHeader header, UITitle title) {

        return create(header, null, title);

    }

    public static UISection create() {

        return create(null, null, null);

    }

    List<UIView> _components;

    public List<UIView> component() {
        return Utility.isNull(this.parent, this)._components;

    }

    UISection parent;
    private int Total;

    public int total() {
        return Utility.isNull(this.parent, this).Total;
    }

    public UISection total(int total) {
        Utility.isNull(this.parent, this).Total = total;
        return this;
    }


    public String Key;

    public boolean IsEditer;

    List<UISection> Sections;
    private Object _data;
    List<WebMeta> data = new LinkedList<>();

    public UISection newSection() {
        UISection t = new UISection();
        t.Sections = this.Sections;
        this.Sections.add(t);
        return t;
    }

    public int size() {

        return this.Sections.size();

    }

    public UISection newSection(Collection data) {
        UISection t = new UISection();
        t.Sections = this.Sections;
        this.Sections.add(t);
        t._data = data;
        return t;
    }

    public UISection addCell(WebMeta... data) {

        this.data.addAll(Arrays.asList(data));
        return this;
    }

    public UISection addCell(UICell... cells) {
        for (int c = 0; c < cells.length; c++)//var sec in this.Sections)
        {
            this.add(cells[c]);
        }
        return this;
    }

    public int length() {
        return data.size();

    }

    public UISection addCell(String text, String value, UIClick click) {
        return this.add(UICell.create("Cell", new WebMeta().put("value", value, "text", text).put("click", click)));

    }

    public UISection addCell(String text, String value, String click) {
        return this.add(UICell.create("Cell", new WebMeta().put("value", value, "text", text).put("click", click)));

    }

    public UISection addCell(String text, UIClick click) {
        return this.add(UICell.create("Cell", new WebMeta().put("text", text).put("click", click)));

    }

    public UISection addCell(String text, String value) {
        return this.add(UICell.create("Cell", new WebMeta().put("value", value, "text", text)));

    }

    public UISection addCell(char icon, String text, String value) {
        return this.add(UICell.create("UI", new WebMeta().put("value", value, "text", text).put("Icon", icon)));

    }

    public UISection addCell(char icon, String text, String value, UIClick click) {
        return this.add(UICell.create("UI", new WebMeta().put("value", value, "text", text).put("Icon", icon).put("click", click)));

    }

    /**
     * 添加支持左滑删除的组件
     *
     * @param cell      行组件
     * @param eventText 删除后请求的事件
     * @return
     */
    public UISection delete(UICell cell, UIEventText eventText) {

        data.add(new WebMeta().put("del", eventText).put("type", cell.type()).put("value", cell.data()).put("format", cell.format()).put("style", cell.style()));
        return this;
    }

    public UISection add(UICell cell) {

        data.add(new WebMeta().put("type", cell.type()).put("value", cell.data()).put("format", cell.format()).put("style", cell.style()));
        return this;
    }


    public UISection add(String type, WebMeta value) {
        data.add(new WebMeta().put("type", type).put("value", value));
        return this;
    }


    public Boolean IsNext;

    public UISection start(boolean IsNext) {
        Utility.isNull(this.parent, this).IsNext = IsNext;
        return this;
    }

    private Integer StartIndex;
    private String StartKey;

    public UISection start(int start) {
        Utility.isNull(this.parent, this).StartIndex = start;
        return this;
    }

    public UISection startKey(String start) {
        Utility.isNull(this.parent, this).StartKey = start;
        return this;
    }


    public void sendTo(WebContext context) {
        this.sendTo(new String[0], context);


    }

    String[] _closeEvents, _refreshEvents;
    WebMeta _submit;
    boolean isOutPageKey;

    public void sendTo(String[] closeEvent, WebContext context, String... refreshEvents) {
        UISection thiz = Utility.isNull(this.parent, this);
        if (Utility.orElse(context.request().sendValues(), r -> r.containsKey("limit"))) {
            context.response().redirect(thiz);
        }
        thiz.isOutPageKey = true;
        thiz._closeEvents = closeEvent;// new String[]{closeEvent};
        thiz._refreshEvents = refreshEvents;
        thiz._submit = new WebMeta("model", context.request()._model, "cmd", context.request()._cmd).put("send", context.request().Arguments);
        context.sendJSON(this, true);
    }

    public void sendTo(String closeEvent, WebContext context, String... refreshEvents) {

        this.sendTo(new String[]{closeEvent}, context, refreshEvents);

    }

    public void sendTo(WebContext context, String... refreshEvents) {
        this.sendTo(new String[0], context, refreshEvents);

    }

    public UISection disableSeparatorLine() {
        disableSeparatorLine = true;
        return this;
    }

    private boolean disableSeparatorLine;

    @Override
    public void read(String key, Object value) {

    }

    @Override
    public void write(Writer writer) {
        UISection thiz = Utility.isNull(this.parent, this);
        try {
            writer.write("{");
            if (thiz.isOutPageKey) {
                UMC.Data.JSON.serialize("type", writer);
                writer.write(":");
                UMC.Data.JSON.serialize("Pager", writer);
                writer.write(",");
                if (Utility.orElse(thiz._closeEvents, r -> r.length) > 0) {
                    UMC.Data.JSON.serialize("CloseEvent", writer);
                    writer.write(":");
                    UMC.Data.JSON.serialize(String.join(",", thiz._closeEvents), writer);
                    writer.write(",");
                }
                if (Utility.orElse(thiz._refreshEvents, r -> r.length) > 0) {
                    UMC.Data.JSON.serialize("RefreshEvent", writer);
                    writer.write(":");
                    UMC.Data.JSON.serialize(String.join(",", _refreshEvents), writer);
                    writer.write(",");
                }
                if (Utility.orElse(thiz._submit, r -> r.size()) > 0) {
                    UMC.Data.JSON.serialize("Submit", writer);
                    writer.write(":");
                    UMC.Data.JSON.serialize(thiz._submit, writer);
                    writer.write(",");
                }
            }
            if (thiz._components != null && thiz._components.size() > 0) {
                UMC.Data.JSON.serialize("Component", writer);
                writer.write(":");
                UMC.Data.JSON.serialize(thiz._components, writer);
                writer.write(",");

            }
            if (thiz._uiHeader != null) {
                UMC.Data.JSON.serialize("Header", writer);
                writer.write(":");
                UMC.Data.JSON.serialize(thiz._uiHeader, writer);
                writer.write(",");
            }
            if (thiz._title != null) {
                UMC.Data.JSON.serialize("Title", writer);
                writer.write(":");
                UMC.Data.JSON.serialize(thiz._title, writer);

                writer.write(",");

            }
            if (thiz._footBar != null) {
                UMC.Data.JSON.serialize("FootBar", writer);
                writer.write(":");
                UMC.Data.JSON.serialize(thiz._footBar, writer);

                writer.write(",");
            }
            if (thiz._uiFooter != null) {
                UMC.Data.JSON.serialize("Footer", writer);
                writer.write(":");
                UMC.Data.JSON.serialize(thiz._uiFooter, writer);

                writer.write(",");
            }
            if (thiz.Total > 0) {
                UMC.Data.JSON.serialize("total", writer);
                writer.write(":");
                UMC.Data.JSON.serialize(thiz.Total, writer);
                writer.write(",");

            }
            if (!Utility.isEmpty(thiz.StartKey)) {

                UMC.Data.JSON.serialize("startKey", writer);
                writer.write(":");
                UMC.Data.JSON.serialize(thiz.StartKey, writer);
                writer.write(",");
            }
            if (thiz.StartIndex != null && thiz.StartIndex > -1) {
                UMC.Data.JSON.serialize("start", writer);
                writer.write(":");
                UMC.Data.JSON.serialize(thiz.StartIndex, writer);
                writer.write(",");

            }
            if (thiz.IsNext != null) {

                UMC.Data.JSON.serialize("next", writer);
                writer.write(":");
                UMC.Data.JSON.serialize(thiz.IsNext, writer);
                writer.write(",");
            }
            UMC.Data.JSON.serialize("DataSource", writer);
            writer.write(":[");
            boolean b = false;
            for (int c = 0; c < this.Sections.size(); c++)//var sec in this.Sections)
            {
                UISection sec = this.Sections.get(c);
                if (b) {
                    writer.write(",");
                } else {
                    b = true;
                }
                writer.write("{");
                if (!Utility.isEmpty(sec.Key)) {
                    UMC.Data.JSON.serialize("key", writer);
                    writer.write(":");
                    UMC.Data.JSON.serialize(sec.Key, writer);
                    writer.write(",");
                }
                if (sec.IsEditer) {
                    UMC.Data.JSON.serialize("isEditer", writer);
                    writer.write(":");
                    UMC.Data.JSON.serialize(sec.IsEditer, writer);
                    writer.write(",");

                }
                if (sec.disableSeparatorLine) {
                    writer.write(",");
                    UMC.Data.JSON.serialize("separatorLine", writer);
                    writer.write(":false");
                }
                UMC.Data.JSON.serialize("data", writer);
                writer.write(":");
                if (sec._data != null) {
                    UMC.Data.JSON.serialize(sec._data, writer);
                } else {
                    UMC.Data.JSON.serialize(sec.data, writer);
                }
                if (sec._header.size() > 0) {
                    writer.write(",");
                    UMC.Data.JSON.serialize("header", writer);
                    writer.write(":");
                    UMC.Data.JSON.serialize(sec._header, writer);
                }
                if (sec._footer.size() > 0) {
                    writer.write(",");
                    UMC.Data.JSON.serialize("footer", writer);
                    writer.write(":");
                    UMC.Data.JSON.serialize(sec._footer, writer);
                }
                writer.write("}");

            }

            writer.write("]}");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}